package com.example.admin.mybledemo.ui;

import android.Manifest;
import android.app.Activity;
import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.text.Layout;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.core.widget.NestedScrollView;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.admin.mybledemo.BleRssiDevice;
import com.example.admin.mybledemo.OtaManager;
import com.example.admin.mybledemo.R;
import com.example.admin.mybledemo.adapter.RecyclerAdapter;
import com.example.admin.mybledemo.adapter.ScanAdapter;
import com.example.admin.mybledemo.ota.OtaDeviceChecker;
import com.example.admin.mybledemo.ota.OtaState;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.net.MalformedURLException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import android.os.Handler;
import android.os.Looper;
import android.database.Cursor;
import android.provider.OpenableColumns;

import cn.com.heaton.blelibrary.ble.Ble;
import cn.com.heaton.blelibrary.ble.BleLog;
import cn.com.heaton.blelibrary.ble.callback.BleConnectCallback;
import cn.com.heaton.blelibrary.ble.callback.BleScanCallback;
import cn.com.heaton.blelibrary.ble.model.BleDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattService;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import android.os.Handler;
import android.os.Looper;

public class OtaActivity extends AppCompatActivity implements RecyclerAdapter.OnItemClickListener<BleRssiDevice>, OtaManager.ConnectionStateListener {

    private static final int REQUEST_PERMISSIONS = 1;
    private static final int REQUEST_LOCATION_PERMISSION = 2;

    private Button btnSelectFile, btnStartScan, btnDownloadFile, btnStartOta, btnClearDevice, btnClearFile, btnConnectDevice, btnCancelOta, btnCopyLog, btnClearLog, btnResetBluetooth;
    private TextView tvFilePath, tvStatus, tvVersionInfo, tvLog, tvSelectedDeviceName, tvSelectedDeviceAddress, tvConnectionStatus;
    private View vConnectionIndicator;
    private EditText etMacCode, etCreditCode, etDownloadUrl;
    private CheckBox cbCheckVersion;
    private RecyclerView rvDevices;
    private ProgressBar pbOta;
    private ScanAdapter scanAdapter;
    private Uri selectedFileUri;
    private List<BleRssiDevice> bleRssiDevices = new ArrayList<>();
    private BleRssiDevice selectedDevice;
    private Ble<BleRssiDevice> ble;
    private LinearLayout llSelectedDevice, llSelectedFile;

    private NestedScrollView nestedScrollView;

    private OtaViewModel otaViewModel;

    private final ActivityResultLauncher<Intent> filePickerLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
                    Uri fileUri = result.getData().getData();
                    if (fileUri != null) {
                        // 验证文件格式
                        if (validateSelectedFile(fileUri)) {
                            selectedFileUri = fileUri;
                    tvFilePath.setText(selectedFileUri.getPath());
                    llSelectedFile.setVisibility(View.VISIBLE);
                    log("Selected file: " + selectedFileUri.getPath());
                    // 选择文件后更新OTA按钮状态
                    updateOtaButtonState();
                        } else {
                            Toast.makeText(this, "请选择有效的.hex文件", Toast.LENGTH_LONG).show();
                            log("文件格式验证失败，请选择有效的.hex文件");
                        }
                    }
                }
            });

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ota);

        otaViewModel = new ViewModelProvider(this).get(OtaViewModel.class);

        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setTitle("OTA");
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        ble = Ble.getInstance();
        initView();
        initLogic();
        OtaManager.getInstance().setConnectionStateListener(this);
        observeViewModel();
    }

    private void initView() {
        btnSelectFile = findViewById(R.id.btn_select_file);
        btnStartScan = findViewById(R.id.btn_start_scan);
        btnDownloadFile = findViewById(R.id.btn_download_file);
        btnStartOta = findViewById(R.id.btn_start_ota);
        btnCancelOta = findViewById(R.id.btn_cancel_ota);
        btnClearDevice = findViewById(R.id.btn_clear_device);
        btnClearFile = findViewById(R.id.btn_clear_file);
        btnConnectDevice = findViewById(R.id.btn_connect_device);
        btnCopyLog = findViewById(R.id.btn_copy_log);
        btnClearLog = findViewById(R.id.btn_clear_log);
        btnResetBluetooth = findViewById(R.id.btn_reset_bluetooth);
        tvFilePath = findViewById(R.id.tv_file_path);
        tvStatus = findViewById(R.id.tv_status);
        tvVersionInfo = findViewById(R.id.tv_version_info);
        tvLog = findViewById(R.id.tv_log);
        tvSelectedDeviceName = findViewById(R.id.tv_selected_device_name);
        tvSelectedDeviceAddress = findViewById(R.id.tv_selected_device_address);
        tvConnectionStatus = findViewById(R.id.tv_connection_status);
        vConnectionIndicator = findViewById(R.id.v_connection_indicator);
        etMacCode = findViewById(R.id.et_mac_code);
        etCreditCode = findViewById(R.id.et_credit_code);
        etDownloadUrl = findViewById(R.id.et_download_url);
        cbCheckVersion = findViewById(R.id.cb_check_version);
        rvDevices = findViewById(R.id.rv_devices);
        pbOta = findViewById(R.id.pb_ota);
        llSelectedDevice = findViewById(R.id.ll_selected_device);
        llSelectedFile = findViewById(R.id.ll_selected_file);
        nestedScrollView = findViewById(R.id.nestedScrollView);

        tvLog.setMovementMethod(new ScrollingMovementMethod());
        rvDevices.setLayoutManager(new LinearLayoutManager(this));
        scanAdapter = new ScanAdapter(this, bleRssiDevices);
        scanAdapter.setOnItemClickListener(this);
        rvDevices.setAdapter(scanAdapter);
    }

    private void initLogic() {
        btnStartOta.setEnabled(false);

        btnDownloadFile.setOnClickListener(v -> {
            String url = etDownloadUrl.getText().toString();
            if (TextUtils.isEmpty(url)) {
                Toast.makeText(this, "Please enter a download URL.", Toast.LENGTH_SHORT).show();
                return;
            }
            // 使用新的下载方式替代AsyncTask
            startDownload(url);
        });

        btnSelectFile.setOnClickListener(v -> {
            // 检查文件权限
            if (!checkFilePermissions()) {
                return;
            }
            
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("*/*");
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            filePickerLauncher.launch(intent);
        });

        btnStartScan.setOnClickListener(v -> {
            if (checkPermissions()) {
                startScan();
            }
        });

        btnStartOta.setOnClickListener(v -> {
            if (selectedDevice == null) {
                Toast.makeText(this, "Please select a device first.", Toast.LENGTH_SHORT).show();
                return;
            }
            if (selectedFileUri == null) {
                Toast.makeText(this, "Please select an OTA file first.", Toast.LENGTH_SHORT).show();
                return;
            }
            
            // 检查文件权限
            if (!checkFilePermissions()) {
                return;
            }
            
            otaViewModel.startOta(selectedDevice, selectedFileUri, etMacCode.getText().toString(), etCreditCode.getText().toString());
        });

        btnCancelOta.setOnClickListener(v -> otaViewModel.cancelOta());

        btnClearDevice.setOnClickListener(v -> {
            selectedDevice = null;
            llSelectedDevice.setVisibility(View.GONE);
            updateOtaButtonState(); // Clear device also updates OTA button state
        });

        btnConnectDevice.setOnClickListener(v -> {
            if (selectedDevice != null) {
                connectToDevice(selectedDevice);
            }
        });

        btnClearFile.setOnClickListener(v -> {
            selectedFileUri = null;
            llSelectedFile.setVisibility(View.GONE);
            updateOtaButtonState(); // Clear file also updates OTA button state
        });

        btnCopyLog.setOnClickListener(v -> {
            ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            cm.setText(tvLog.getText());
            Toast.makeText(this, "Log copied to clipboard", Toast.LENGTH_SHORT).show();
        });

        btnClearLog.setOnClickListener(v -> {
            tvLog.setText("日志:\n");
        });

        btnResetBluetooth.setOnClickListener(v -> {
            resetBluetoothState();
        });

        tvLog.setOnTouchListener((v, event) -> {
            nestedScrollView.requestDisallowInterceptTouchEvent(true);
            return false;
        });

        rvDevices.setOnTouchListener((v, event) -> {
            nestedScrollView.requestDisallowInterceptTouchEvent(true);
            return false;
        });
    }

    private void observeViewModel() {
        otaViewModel.otaState.observe(this, state -> {
            tvStatus.setText("Status: " + state.getDescription());
            log("OTA State: " + state.getDescription());
            if (state == OtaState.FAILED || state == OtaState.COMPLETED || state == OtaState.IDLE || state == OtaState.CANCELLED) {
                pbOta.setProgress(0);
                updateUiForOtaStart(false);
                // 当OTA结束时（无论成功、失败、取消还是空闲），更新OTA按钮状态
                updateOtaButtonState();
            } else {
                updateUiForOtaStart(true);
            }
        });

        otaViewModel.progress.observe(this, progress -> pbOta.setProgress(progress));

        otaViewModel.logMessages.observe(this, this::log);

        otaViewModel.errorMessages.observe(this, error -> {
            log("OTA Error: " + error);
            Toast.makeText(this, "升级失败: " + error, Toast.LENGTH_LONG).show();
        });
    }

    private void updateUiForOtaStart(boolean isStarting) {
        if (isStarting) {
            btnStartOta.setVisibility(View.GONE);
            btnCancelOta.setVisibility(View.VISIBLE);
            btnStartScan.setEnabled(false);
            btnSelectFile.setEnabled(false);
            btnDownloadFile.setEnabled(false);
        } else {
            btnStartOta.setVisibility(View.VISIBLE);
            btnCancelOta.setVisibility(View.GONE);
            btnStartScan.setEnabled(true);
            btnSelectFile.setEnabled(true);
            btnDownloadFile.setEnabled(true);
        }
    }

    private boolean checkFilePermissions() {
        List<String> permissionsNeeded = new ArrayList<>();
        
        // 文件读取权限（Android 6.0+）
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }
        
        // 文件写入权限（Android 6.0+，Android 11以下需要）
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R && 
            ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        
        // 如果有权限未授予，请求权限
        if (!permissionsNeeded.isEmpty()) {
            log("检测到文件权限未授予，正在请求文件权限...");
            log("需要权限: " + String.join(", ", permissionsNeeded));
            
            String[] permissions = permissionsNeeded.toArray(new String[0]);
            ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSIONS);
            
            Toast.makeText(this, "文件操作需要存储权限，请在弹窗中允许", Toast.LENGTH_LONG).show();
            return false;
        }
        
        log("文件权限检查通过");
        return true;
    }

    private boolean checkPermissions() {
        List<String> permissions = new ArrayList<>();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            permissions.add(Manifest.permission.BLUETOOTH_SCAN);
            permissions.add(Manifest.permission.BLUETOOTH_ADVERTISE);
            permissions.add(Manifest.permission.BLUETOOTH_CONNECT);
        } else {
            permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
            permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
            permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            permissions.add(Manifest.permission.FOREGROUND_SERVICE);
        }
        List<String> permissionsToRequest = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                permissionsToRequest.add(permission);
            }
        }
        if (!permissionsToRequest.isEmpty()) {
            ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), REQUEST_PERMISSIONS);
            return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        
        if (requestCode == REQUEST_PERMISSIONS) {
            boolean allPermissionsGranted = true;
            
            // 检查所有权限是否都已授予
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    log("权限被拒绝: " + permissions[i]);
                    allPermissionsGranted = false;
                }
            }
            
            if (allPermissionsGranted) {
                log("所有权限已授予，现在可以开始扫描");
                Toast.makeText(this, "所有权限已授予，开始扫描", Toast.LENGTH_SHORT).show();
                // 所有权限授予后自动开始扫描
                startScan();
            } else {
                log("部分权限被拒绝，BLE功能可能无法正常工作");
                Toast.makeText(this, "部分权限被拒绝，BLE功能可能无法正常工作", Toast.LENGTH_LONG).show();
                
                // 显示详细的权限说明
                StringBuilder deniedPermissions = new StringBuilder();
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        if (deniedPermissions.length() > 0) {
                            deniedPermissions.append(", ");
                        }
                        deniedPermissions.append(permissions[i]);
                    }
                }
                log("被拒绝的权限: " + deniedPermissions.toString());
                log("请在设置中手动授予这些权限");
            }
        }
    }

    private void startScan() {
        log("开始蓝牙扫描...");
        log("当前蓝牙状态: " + (ble.isBleEnable() ? "已开启" : "未开启"));
        
        // 检查所有需要的权限
        List<String> permissionsNeeded = new ArrayList<>();
        
        // 位置权限（Android 6.0+）
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        
        // 蓝牙扫描权限（Android 12+）
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && 
            ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
            permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN);
        }
        
        // 蓝牙连接权限（Android 12+）
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && 
            ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT);
        }
        
        // 如果有权限未授予，一次性请求所有权限
        if (!permissionsNeeded.isEmpty()) {
            log("检测到权限未授予，正在请求所有必要权限...");
            log("需要权限: " + String.join(", ", permissionsNeeded));
            
            String[] permissions = permissionsNeeded.toArray(new String[0]);
            ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSIONS);
            
            Toast.makeText(this, "BLE功能需要位置和蓝牙权限，请在弹窗中允许", Toast.LENGTH_LONG).show();
            return;
        }
        
        // 所有权限都已授予，记录权限状态
        boolean hasLocationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        boolean hasBluetoothScanPermission = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || 
            ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;
        boolean hasBluetoothConnectPermission = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || 
            ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED;
        
        log("权限状态 - 位置权限: " + (hasLocationPermission ? "已授予" : "未授予"));
        log("权限状态 - 蓝牙扫描权限: " + (hasBluetoothScanPermission ? "已授予" : "未授予"));
        log("权限状态 - 蓝牙连接权限: " + (hasBluetoothConnectPermission ? "已授予" : "未授予"));
        
        if (!ble.isBleEnable()) {
            log("蓝牙未开启，请先开启蓝牙");
            Toast.makeText(this, "请先开启蓝牙", Toast.LENGTH_SHORT).show();
            return;
        }
        
        // 检查是否已经在扫描
        if (ble.isScanning()) {
            log("扫描已经在进行中，请等待当前扫描完成");
            Toast.makeText(this, "扫描已经在进行中，请等待完成", Toast.LENGTH_SHORT).show();
            return;
        }
        
        bleRssiDevices.clear();
        scanAdapter.notifyDataSetChanged();
        
        try {
        ble.startScan(new BleScanCallback<BleRssiDevice>() {
            @Override
            public void onStart() {
                log("扫描开始...");
            }
            
            @Override
            public void onStop() {
                log("扫描停止，共发现 " + bleRssiDevices.size() + " 个设备");
            }
            
            @Override
            public void onLeScan(BleRssiDevice device, int rssi, byte[] scanRecord) {
                    log("发现设备: " + device.getBleName() + " (" + device.getBleAddress() + ") RSSI: " + rssi);
                synchronized (ble.getLocker()) {
                    for (int i = 0; i < bleRssiDevices.size(); i++) {
                        if (TextUtils.equals(bleRssiDevices.get(i).getBleAddress(), device.getBleAddress())) {
                            return;
                        }
                    }
                    bleRssiDevices.add(device);
                        runOnUiThread(() -> {
                    scanAdapter.notifyDataSetChanged();
                            log("设备列表已更新，当前设备数: " + bleRssiDevices.size());
                        });
                    }
                }
                
                @Override
                public void onScanFailed(int errorCode) {
                    log("蓝牙扫描失败，错误码: " + errorCode);
                    final String errorMessage;
                    switch (errorCode) {
                        // Android系统扫描错误码
                        case 1: // SCAN_FAILED_ALREADY_STARTED
                            errorMessage = "扫描已经在进行中";
                            break;
                        case 2: // SCAN_FAILED_APPLICATION_REGISTRATION_FAILED
                            errorMessage = "应用注册失败";
                            break;
                        case 3: // SCAN_FAILED_INTERNAL_ERROR
                            errorMessage = "内部错误";
                            break;
                        case 4: // SCAN_FAILED_FEATURE_UNSUPPORTED
                            errorMessage = "设备不支持BLE扫描";
                            break;
                        case 5: // SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES
                            errorMessage = "硬件资源不足";
                            break;
                        case 6: // SCAN_FAILED_SCANNING_TOO_FREQUENTLY
                            errorMessage = "扫描过于频繁";
                            break;
                        case 7: // SCAN_FAILED_FEATURE_UNSUPPORTED
                            errorMessage = "功能不支持";
                            break;
                        case 8: // SCAN_FAILED_BLUETOOTH_DISABLED
                            errorMessage = "蓝牙已禁用";
                            break;
                        case 9: // SCAN_FAILED_LOCATION_DISABLED
                            errorMessage = "位置服务已禁用";
                            break;
                        case 10: // SCAN_FAILED_INSUFFICIENT_PERMISSIONS
                            errorMessage = "权限不足";
                            break;
                        // BLE库内部错误码
                        case 2000: // NotInit
                            errorMessage = "BLE库未初始化";
                            break;
                        case 2001: // InitAlready
                            errorMessage = "BLE库已初始化";
                            break;
                        case 2005: // NotSupportBLE
                            errorMessage = "设备不支持BLE";
                            break;
                        case 2006: // BluetoothNotOpen
                            errorMessage = "蓝牙未开启";
                            break;
                        case 2007: // NotAvailable
                            errorMessage = "蓝牙不可用";
                            break;
                        case 2008: // BlePermissionError
                            errorMessage = "BLE权限错误";
                            break;
                        case 2009: // NotFindDevice
                            errorMessage = "未找到设备";
                            break;
                        case 2010: // InvalidAddress
                            errorMessage = "无效地址";
                            break;
                        case 2020: // ScanAlready
                            errorMessage = "扫描已经在进行中，请等待当前扫描完成";
                            break;
                        case 2021: // ScanStopAlready
                            errorMessage = "扫描已经停止";
                            break;
                        case 2022: // ScanFrequentlyError
                            errorMessage = "扫描过于频繁，请稍后重试";
                            break;
                        case 2023: // ScanError
                            errorMessage = "扫描错误";
                            break;
                        default:
                            errorMessage = "未知错误码: " + errorCode + " (请检查蓝牙权限、位置服务和设备兼容性)";
                            break;
                    }
                    log("扫描失败详情: " + errorMessage);
                    
                    // 针对特定错误码提供具体解决方案
                    if (errorCode == 2020) { // ScanAlready
                        log("解决方案: 当前扫描正在进行中，请等待扫描完成或使用'重置蓝牙'功能");
                    } else if (errorCode == 2008) { // BlePermissionError
                        log("解决方案: 请授予位置权限和蓝牙权限");
                    } else if (errorCode == 2006) { // BluetoothNotOpen
                        log("解决方案: 请开启蓝牙");
                    } else {
                        log("建议解决方案: 1.检查蓝牙是否开启 2.检查位置权限 3.重启蓝牙 4.检查设备兼容性");
                    }
                    
                    runOnUiThread(() -> {
                        Toast.makeText(OtaActivity.this, "蓝牙扫描失败: " + errorMessage, Toast.LENGTH_LONG).show();
                    });
                }
            });
            log("蓝牙扫描启动成功");
        } catch (Exception e) {
            log("蓝牙扫描启动异常: " + e.getMessage());
            Toast.makeText(this, "蓝牙扫描启动失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            this.finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onItemClick(ViewGroup parent, View view, BleRssiDevice bleRssiDevice, int position) {
        selectedDevice = bleRssiDevice;
        String deviceName = bleRssiDevice.getBleName();
        if (TextUtils.isEmpty(deviceName)) {
            deviceName = "Unknown Device";
        }
        tvSelectedDeviceName.setText(deviceName);
        tvSelectedDeviceAddress.setText(bleRssiDevice.getBleAddress());
        
        updateConnectionStatus(false, false);
        
        llSelectedDevice.setVisibility(View.VISIBLE);
        Toast.makeText(this, "已选择设备: " + deviceName, Toast.LENGTH_SHORT).show();
        
        // 选择设备后连接并检查OTA服务（与Flutter端保持一致）
        connectAndCheckOtaService(bleRssiDevice);
    }

    public void onConnectionStateChanged(BleDevice device) {
        if (selectedDevice != null && selectedDevice.getBleAddress().equals(device.getBleAddress())) {
            runOnUiThread(() -> {
                updateConnectionStatus(device.isConnected(), device.isConnecting());
                // 同时更新OTA按钮状态
                updateOtaButtonState();
            });
        }
    }
    
    /**
     * 检查并更新OTA按钮的启用状态
     */
    private void updateOtaButtonState() {
        boolean shouldEnable = shouldEnableOtaButton();
        btnStartOta.setEnabled(shouldEnable);
        log("OTA按钮状态更新: " + (shouldEnable ? "启用" : "禁用"));
    }
    
    /**
     * 判断OTA按钮是否应该启用
     */
    private boolean shouldEnableOtaButton() {
        // 检查是否有选中的设备
        if (selectedDevice == null) {
            log("OTA按钮禁用原因: 未选择设备");
            return false;
        }
        
        // 检查设备是否已连接
        boolean isConnected = false;
        for (BleRssiDevice connectedDevice : ble.getConnectedDevices()) {
            if (connectedDevice.getBleAddress().equals(selectedDevice.getBleAddress())) {
                isConnected = true;
                break;
            }
        }
        
        if (!isConnected) {
            log("OTA按钮禁用原因: 设备未连接");
            return false;
        }
        
        // 检查是否选择了文件
        if (selectedFileUri == null) {
            log("OTA按钮禁用原因: 未选择OTA文件");
            return false;
        }
        
        // 检查是否正在进行OTA - 修复取消后无法再次升级的问题
        OtaState currentState = otaViewModel.otaState.getValue();
        if (currentState != null) {
            // 只有在真正进行中的状态才禁用按钮，IDLE、COMPLETED、FAILED、CANCELLED都允许开始新的OTA
            boolean isActivelyInProgress = (currentState != OtaState.IDLE &&
                                          currentState != OtaState.COMPLETED &&
                                          currentState != OtaState.FAILED &&
                                          currentState != OtaState.CANCELLED);
            if (isActivelyInProgress) {
                log("OTA按钮禁用原因: OTA正在进行中 (" + currentState.getDescription() + ")");
                return false;
            }
        }
        
        log("OTA按钮启用: 所有条件满足");
        return true;
    }

    private void log(String message) {
        runOnUiThread(() -> {
            tvLog.append(message + "\n");
            tvLog.postDelayed(() -> {
                if (tvLog.getLayout() != null) {
                    int scrollAmount = tvLog.getLayout().getLineTop(tvLog.getLineCount()) - tvLog.getHeight();
                    if (scrollAmount > 0) {
                        tvLog.scrollTo(0, scrollAmount);
                    } else {
                        tvLog.scrollTo(0, 0);
                    }
                }
            }, 10); // 添加 10ms 延迟确保布局完成
        });
    }

    /**
     * 新的下载方法，替代已弃用的AsyncTask
     */
    private void startDownload(String url) {
        // 检查网络权限
        if (!checkNetworkPermission()) {
            Toast.makeText(this, "需要网络权限才能下载文件", Toast.LENGTH_SHORT).show();
            return;
        }

        // 显示下载进度
        pbOta.setIndeterminate(false);
        pbOta.setMax(100);
        pbOta.setProgress(0);
        Toast.makeText(this, "开始下载文件...", Toast.LENGTH_SHORT).show();

        // 使用ExecutorService替代AsyncTask
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Handler mainHandler = new Handler(Looper.getMainLooper());

        executor.execute(() -> {
            InputStream input = null;
            OutputStream output = null;
            HttpURLConnection connection = null;
            String result = null;

            try {
                // 验证URL格式
                if (!isValidUrl(url)) {
                    result = "无效的URL格式";
                    return;
                }

                URL downloadUrl = new URL(url);
                connection = (HttpURLConnection) downloadUrl.openConnection();
                
                // 设置连接参数，提高兼容性
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(30000); // 30秒连接超时
                connection.setReadTimeout(60000);    // 60秒读取超时
                connection.setRequestProperty("User-Agent", "Android-BLE-OTA/1.0");
                connection.setRequestProperty("Accept", "*/*");
                
                connection.connect();

                int responseCode = connection.getResponseCode();
                if (responseCode != HttpURLConnection.HTTP_OK) {
                    result = "服务器返回错误: HTTP " + responseCode + " " + connection.getResponseMessage();
                    return;
                }

                int fileLength = connection.getContentLength();
                if (fileLength <= 0) {
                    result = "无法获取文件大小";
                    return;
                }

                // 检查可用存储空间
                if (!checkStorageSpace(fileLength)) {
                    result = "存储空间不足";
                    return;
                }

                // 创建临时文件
                File tempFile = new File(getCacheDir(), "ota_update_" + System.currentTimeMillis() + ".bin");
                input = connection.getInputStream();
                output = new FileOutputStream(tempFile);

                byte[] data = new byte[8192]; // 增加缓冲区大小
                long total = 0;
                int count;
                long lastProgressUpdate = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    output.write(data, 0, count);

                    // 更新进度，但限制更新频率
                    long currentTime = System.currentTimeMillis();
                    if (currentTime - lastProgressUpdate > 100) { // 每100ms更新一次
                        final int progress = (int) (total * 100 / fileLength);
                        mainHandler.post(() -> {
                            try {
                                pbOta.setProgress(progress);
                            } catch (Exception e) {
                                log("更新进度失败: " + e.getMessage());
                            }
                        });
                        lastProgressUpdate = currentTime;
                    }
                }

                // 验证文件完整性
                if (tempFile.length() != fileLength) {
                    result = "文件下载不完整";
                    tempFile.delete();
                    return;
                }

                // 验证文件格式（检查是否为.hex文件）
                if (!isValidHexFile(tempFile)) {
                    result = "文件格式错误，请选择有效的.hex文件";
                    tempFile.delete();
                    return;
                }

                // 下载完成，创建FileProvider URI
                selectedFileUri = FileProvider.getUriForFile(
                    OtaActivity.this, 
                    getApplicationContext().getPackageName() + ".fileprovider", 
                    tempFile
                );

            } catch (MalformedURLException e) {
                result = "URL格式错误: " + e.getMessage();
                log("下载错误 - URL格式错误: " + e.getMessage());
            } catch (ConnectException e) {
                result = "网络连接失败，请检查网络设置";
                log("下载错误 - 网络连接失败: " + e.getMessage());
            } catch (SocketTimeoutException e) {
                result = "下载超时，请重试";
                log("下载错误 - 超时: " + e.getMessage());
            } catch (IOException e) {
                result = "文件下载失败: " + e.getMessage();
                log("下载错误 - IO异常: " + e.getMessage());
            } catch (SecurityException e) {
                result = "权限不足，无法下载文件";
                log("下载错误 - 权限异常: " + e.getMessage());
            } catch (OutOfMemoryError e) {
                result = "内存不足，无法下载大文件";
                log("下载错误 - 内存不足: " + e.getMessage());
            } catch (Exception e) {
                result = "未知错误: " + e.getMessage();
                log("下载错误 - 未知异常: " + e.getMessage());
            } finally {
                try {
                    if (output != null) output.close();
                    if (input != null) input.close();
                } catch (IOException ignored) {
                    log("关闭流时发生异常，已忽略");
                }
                if (connection != null) connection.disconnect();
            }

            // 在主线程中处理结果
            final String finalResult = result;
            mainHandler.post(() -> {
                try {
                    pbOta.setProgress(0);
                    if (finalResult != null) {
                        Toast.makeText(OtaActivity.this, "下载失败: " + finalResult, Toast.LENGTH_LONG).show();
                        log("下载失败: " + finalResult);
                    } else {
                        Toast.makeText(OtaActivity.this, "文件下载成功", Toast.LENGTH_SHORT).show();
                        tvFilePath.setText(selectedFileUri.getPath());
                        llSelectedFile.setVisibility(View.VISIBLE);
                        log("文件下载成功: " + selectedFileUri.getPath());
                        updateOtaButtonState();
                    }
                } catch (Exception e) {
                    log("处理下载结果失败: " + e.getMessage());
                    Toast.makeText(OtaActivity.this, "处理下载结果失败", Toast.LENGTH_SHORT).show();
                }
            });
        });

        executor.shutdown();
    }

    /**
     * 检查网络权限
     */
    private boolean checkNetworkPermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) == PackageManager.PERMISSION_GRANTED &&
               ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * 验证URL格式
     */
    private boolean isValidUrl(String url) {
        try {
            new URL(url);
            return true;
        } catch (MalformedURLException e) {
            return false;
        }
    }

    /**
     * 检查存储空间
     */
    private boolean checkStorageSpace(long requiredBytes) {
        try {
            File cacheDir = getCacheDir();
            long availableSpace = cacheDir.getFreeSpace();
            
            // 检查可用存储空间
            if (availableSpace <= requiredBytes + 1024 * 1024) { // 额外预留1MB
                log("存储空间不足: 需要 " + (requiredBytes / 1024 / 1024) + "MB, 可用 " + (availableSpace / 1024 / 1024) + "MB");
                return false;
            }
            
            // 检查内存使用情况
            Runtime runtime = Runtime.getRuntime();
            long maxMemory = runtime.maxMemory();
            long usedMemory = runtime.totalMemory() - runtime.freeMemory();
            long availableMemory = maxMemory - usedMemory;
            
            // 如果文件太大，检查内存是否足够
            if (requiredBytes > 10 * 1024 * 1024) { // 大于10MB的文件
                if (availableMemory < requiredBytes * 2) { // 需要2倍文件大小的内存
                    log("内存不足: 文件大小 " + (requiredBytes / 1024 / 1024) + "MB, 可用内存 " + (availableMemory / 1024 / 1024) + "MB");
                    return false;
                }
            }
            
            return true;
        } catch (Exception e) {
            log("检查存储空间失败: " + e.getMessage());
            return true; // 如果检查失败，允许继续下载
        }
    }

    /**
     * 验证文件是否为有效的.hex文件
     */
    private boolean isValidHexFile(File file) {
        try {
            if (!file.exists() || file.length() == 0) {
                log("文件不存在或为空");
                return false;
            }

            // 检查文件扩展名
            String fileName = file.getName().toLowerCase();
            if (!fileName.endsWith(".hex")) {
                log("文件扩展名不是.hex: " + fileName);
                return false;
            }

            // 读取文件前几行验证格式
            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                String firstLine = reader.readLine();
                if (firstLine == null || firstLine.trim().isEmpty()) {
                    log("文件第一行为空");
                    return false;
                }

                // 检查是否包含典型的.hex文件特征
                // .hex文件通常以":"开头，或者包含十六进制数据
                String trimmedLine = firstLine.trim();
                if (trimmedLine.startsWith(":") || 
                    trimmedLine.matches("^[0-9A-Fa-f\\s]+$") ||
                    trimmedLine.startsWith("@")) {
                    log("文件格式验证通过: " + trimmedLine.substring(0, Math.min(50, trimmedLine.length())));
                    return true;
                } else {
                    log("文件格式不符合.hex文件特征: " + trimmedLine.substring(0, Math.min(50, trimmedLine.length())));
                    return false;
                }
            }
        } catch (Exception e) {
            log("文件格式验证失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 验证选择的文件是否为有效的.hex文件
     */
    private boolean validateSelectedFile(Uri fileUri) {
        try {
            // 检查文件扩展名
            String fileName = getFileName(fileUri);
            if (fileName == null || !fileName.toLowerCase().endsWith(".hex")) {
                log("文件扩展名不是.hex: " + fileName);
                return false;
            }

            // 读取文件前几行验证格式
            try (InputStream inputStream = getContentResolver().openInputStream(fileUri);
                 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
                
                String firstLine = reader.readLine();
                if (firstLine == null || firstLine.trim().isEmpty()) {
                    log("文件第一行为空");
                    return false;
                }

                // 检查是否包含典型的.hex文件特征
                String trimmedLine = firstLine.trim();
                if (trimmedLine.startsWith(":") || 
                    trimmedLine.matches("^[0-9A-Fa-f\\s]+$") ||
                    trimmedLine.startsWith("@")) {
                    log("文件格式验证通过: " + trimmedLine.substring(0, Math.min(50, trimmedLine.length())));
                    return true;
                } else {
                    log("文件格式不符合.hex文件特征: " + trimmedLine.substring(0, Math.min(50, trimmedLine.length())));
                    return false;
                }
            }
        } catch (Exception e) {
            log("文件格式验证失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 从URI获取文件名
     */
    private String getFileName(Uri uri) {
        String result = null;
        if (uri.getScheme().equals("content")) {
            try (Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
                if (cursor != null && cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                    if (index >= 0) {
                        result = cursor.getString(index);
                    }
                }
            } catch (Exception e) {
                log("获取文件名失败: " + e.getMessage());
            }
        }
        if (result == null) {
            result = uri.getPath();
            int cut = result.lastIndexOf('/');
            if (cut != -1) {
                result = result.substring(cut + 1);
            }
        }
        return result;
    }

    /**
     * 旧的AsyncTask类，保留作为备用方案
     */
    private class DownloadFileTask extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... sUrl) {
            InputStream input = null;
            OutputStream output = null;
            HttpURLConnection connection = null;
            try {
                URL url = new URL(sUrl[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(30000);
                connection.setReadTimeout(60000);
                connection.connect();

                if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                    return "Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage();
                }

                int fileLength = connection.getContentLength();

                File file = new File(getCacheDir(), "ota_update.bin");
                selectedFileUri = FileProvider.getUriForFile(OtaActivity.this, getApplicationContext().getPackageName() + ".fileprovider", file);
                input = connection.getInputStream();
                output = new FileOutputStream(file);

                byte[] data = new byte[4096];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    if (isCancelled()) {
                        input.close();
                        return null;
                    }
                    total += count;
                    if (fileLength > 0) publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }
            } catch (Exception e) {
                return e.toString();
            } finally {
                try {
                    if (output != null) output.close();
                    if (input != null) input.close();
                } catch (IOException ignored) {
                }

                if (connection != null) connection.disconnect();
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Toast.makeText(OtaActivity.this, "Downloading file...", Toast.LENGTH_SHORT).show();
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            pbOta.setIndeterminate(false);
            pbOta.setMax(100);
            pbOta.setProgress(progress[0]);
        }

        @Override
        protected void onPostExecute(String result) {
            pbOta.setProgress(0);
            if (result != null)
                Toast.makeText(OtaActivity.this, "Download error: " + result, Toast.LENGTH_LONG).show();
            else {
                Toast.makeText(OtaActivity.this, "File downloaded", Toast.LENGTH_SHORT).show();
                tvFilePath.setText(selectedFileUri.getPath());
                llSelectedFile.setVisibility(View.VISIBLE);
                log("Downloaded file to: " + selectedFileUri.getPath());
                updateOtaButtonState(); // Download complete also updates OTA button state
            }
        }
    }

    private void connectToDevice(BleRssiDevice device) {
        if (device == null) return;
        
        String deviceName = device.getBleName();
        if (TextUtils.isEmpty(deviceName)) {
            deviceName = "Unknown Device";
        }
        
        updateConnectionStatus(false, true);
        Toast.makeText(this, "正在连接: " + deviceName, Toast.LENGTH_SHORT).show();

        ble.connect(device, new BleConnectCallback<>() {
            @Override
            public void onConnectionChanged(final BleRssiDevice device) {
                runOnUiThread(() -> {
                    if (device.isConnected()) {
                        log("已连接到 " + device.getBleName());
                        updateConnectionStatus(true, false);
                        btnStartOta.setEnabled(true);
                        Toast.makeText(OtaActivity.this, "设备已连接", Toast.LENGTH_SHORT).show();
                    } else if (device.isDisconnected()) {
                        log("已断开连接 " + device.getBleName());
                        updateConnectionStatus(false, false);
                        btnStartOta.setEnabled(false);
                        Toast.makeText(OtaActivity.this, "设备已断开", Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onConnectFailed(final BleRssiDevice device, final int errorCode) {
                runOnUiThread(() -> {
                    log("连接失败 " + device.getBleName() + ", 错误代码: " + errorCode);
                    
                    String errorMessage = "连接失败";
                    switch (errorCode) {
                        case 8: // GATT_INSUFFICIENT_AUTHENTICATION
                            errorMessage = "认证不足，需要配对";
                            break;
                        case 15: // GATT_INSUFFICIENT_ENCRYPTION
                            errorMessage = "需要加密连接";
                            break;
                        case 19: // GATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE
                            errorMessage = "加密密钥长度不足";
                            break;
                        case 22: // GATT_INVALID_ATTRIBUTE_LENGTH
                            errorMessage = "属性长度无效";
                            break;
                        case 133: // GATT_ERROR
                            errorMessage = "GATT错误，设备可能不支持";
                            break;
                        case 257: // GATT_INTERNAL_ERROR
                            errorMessage = "GATT内部错误";
                            break;
                        case 258: // GATT_WRONG_STATE
                            errorMessage = "GATT状态错误";
                            break;
                        case 259: // GATT_DB_FULL
                            errorMessage = "GATT数据库已满";
                            break;
                        case 260: // GATT_BUSY
                            errorMessage = "GATT忙，请稍后重试";
                            break;
                        case 261: // GATT_ERROR_RSP
                            errorMessage = "GATT响应错误";
                            break;
                        case 262: // GATT_CMD_STARTED
                            errorMessage = "GATT命令已开始";
                            break;
                        case 263: // GATT_ILLEGAL_PARAMETER
                            errorMessage = "GATT参数非法";
                            break;
                        case 264: // GATT_PENDING
                            errorMessage = "GATT操作挂起";
                            break;
                        case 265: // GATT_AUTH_FAIL
                            errorMessage = "GATT认证失败";
                            break;
                        case 266: // GATT_MORE
                            errorMessage = "GATT需要更多数据";
                            break;
                        case 267: // GATT_INVALID_CFG
                            errorMessage = "GATT配置无效";
                            break;
                        case 268: // GATT_SERVICE_STARTED
                            errorMessage = "GATT服务已开始";
                            break;
                        case 269: // GATT_EXC_LEN_VALID
                            errorMessage = "GATT长度验证异常";
                            break;
                        case 270: // GATT_DIFFERENT_KEY_TYPE
                            errorMessage = "GATT密钥类型不同";
                            break;
                        case 271: // GATT_PRC_IN_PROGRESS
                            errorMessage = "GATT配对进行中";
                            break;
                        default:
                            errorMessage = "连接失败，错误码: " + errorCode;
                            break;
                    }
                    
                    log("连接失败详情: " + errorMessage);
                    log("建议解决方案: 1.检查设备是否在范围内 2.重启蓝牙 3.检查设备是否支持BLE 4.尝试重新扫描");
                    
                    updateConnectionStatus(false, false);
                    btnStartOta.setEnabled(false);
                    Toast.makeText(OtaActivity.this, "连接失败: " + errorMessage, Toast.LENGTH_LONG).show();
                });
            }
        });
    }

    private void updateConnectionStatus(boolean isConnected, boolean isConnecting) {
        if (isConnecting) {
            tvConnectionStatus.setText("连接中...");
            vConnectionIndicator.setBackgroundTintList(
                android.content.res.ColorStateList.valueOf(getResources().getColor(R.color.device_connecting))
            );
            llSelectedDevice.setBackgroundTintList(
                android.content.res.ColorStateList.valueOf(getResources().getColor(R.color.md_warning_container))
            );
            btnConnectDevice.setText("连接中...");
            btnConnectDevice.setEnabled(false);
        } else if (isConnected) {
            tvConnectionStatus.setText("已连接");
            vConnectionIndicator.setBackgroundTintList(
                android.content.res.ColorStateList.valueOf(getResources().getColor(R.color.device_connected))
            );
            llSelectedDevice.setBackgroundTintList(
                android.content.res.ColorStateList.valueOf(getResources().getColor(R.color.md_success_container))
            );
            btnConnectDevice.setText("已连接");
            btnConnectDevice.setEnabled(false);
        } else {
            tvConnectionStatus.setText("未连接");
            vConnectionIndicator.setBackgroundTintList(
                android.content.res.ColorStateList.valueOf(getResources().getColor(R.color.device_disconnected))
            );
            llSelectedDevice.setBackgroundTintList(
                android.content.res.ColorStateList.valueOf(getResources().getColor(R.color.md_warning_container))
            );
            btnConnectDevice.setText("连接设备");
            btnConnectDevice.setEnabled(true);
        }
    }

    private void resetBluetoothState() {
        log("正在重置蓝牙状态...");
        try {
            // Stop scanning if active
            if (ble.isScanning()) {
                ble.stopScan();
                log("停止当前扫描");
            }

            // Disconnect all connected devices
            for (BleRssiDevice device : ble.getConnectedDevices()) {
                ble.disconnect(device);
                log("断开设备连接: " + device.getBleName());
            }

            // Clear local device list
            bleRssiDevices.clear();
            scanAdapter.notifyDataSetChanged();
            log("清空设备列表");

            // Reset selected device
            selectedDevice = null;
            llSelectedDevice.setVisibility(View.GONE);
            log("重置选中设备");

            // Clear connection status
            updateConnectionStatus(false, false);

            // Brief delay before allowing new scan
            btnStartScan.postDelayed(() -> {
                btnStartScan.setEnabled(true);
                log("蓝牙状态重置完成，可以重新扫描");
                // 重置完成后也更新OTA按钮状态
                updateOtaButtonState();
            }, 1000);

            btnStartScan.setEnabled(false);
            Toast.makeText(this, "蓝牙状态已重置，请稍后重新扫描", Toast.LENGTH_SHORT).show();
            log("蓝牙状态重置完成");
        } catch (Exception e) {
            log("重置蓝牙状态失败: " + e.getMessage());
            Toast.makeText(this, "重置蓝牙状态失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }
    
    /**
     * 连接设备并检查OTA服务（与Flutter端保持一致）
     * 类似Flutter端的afterDiscoverService逻辑
     */
    private void connectAndCheckOtaService(BleRssiDevice device) {
        log("连接设备并检查OTA服务: " + device.getBleName());
        updateConnectionStatus(false, true); // 显示连接中状态
        
        // 先停止扫描
        ble.stopScan();
        
        ble.connect(device, new BleConnectCallback<BleRssiDevice>() {
            @Override
            public void onConnectionChanged(BleRssiDevice bleDevice) {
                log("设备连接状态变化: " + bleDevice.isConnected());
                runOnUiThread(() -> {
                    updateConnectionStatus(bleDevice.isConnected(), bleDevice.isConnecting());
                    
                    // 如果连接成功，等待服务发现
                    if (bleDevice.isConnected()) {
                        log("设备连接成功，等待服务发现: " + bleDevice.getBleName());
                    }
                });
            }

            @Override
            public void onConnectCancel(BleRssiDevice bleDevice) {
                log("设备连接取消: " + bleDevice.getBleName());
                runOnUiThread(() -> {
                    updateConnectionStatus(false, false);
                    Toast.makeText(OtaActivity.this, "连接已取消", Toast.LENGTH_SHORT).show();
                    updateOtaButtonState();
                });
            }

            @Override
            public void onConnectFailed(BleRssiDevice bleDevice, int errorCode) {
                log("设备连接失败: " + bleDevice.getBleName() + ", 错误码: " + errorCode);
                runOnUiThread(() -> {
                    updateConnectionStatus(false, false);
                    Toast.makeText(OtaActivity.this, "连接失败: " + errorCode, Toast.LENGTH_SHORT).show();
                    updateOtaButtonState();
                });
            }
            
            @Override
            public void onServicesDiscovered(BleRssiDevice device, BluetoothGatt gatt) {
                log("服务发现完成，开始检查OTA服务: " + device.getBleName());
                
                // 在服务发现完成后检查OTA支持
                checkOtaServiceFromGatt(device, gatt);
            }
        });
    }
    
    /**
     * 从BluetoothGatt中检查OTA支持
     */
    private void checkOtaServiceFromGatt(BleRssiDevice device, BluetoothGatt gatt) {
        log("开始检查OTA服务...");
        
        // 延迟一下确保连接稳定
        new Handler(Looper.getMainLooper()).postDelayed(() -> {
            try {
                List<BluetoothGattService> services = gatt.getServices();
                if (services == null || services.isEmpty()) {
                    log("服务列表为空，尝试重新发现服务");
                    // 如果服务为空，可能需要刷新服务发现
                                                        runOnUiThread(() -> {
                        Toast.makeText(OtaActivity.this, "设备服务发现失败，请重试", Toast.LENGTH_SHORT).show();
                        ble.disconnect(device);
                        updateConnectionStatus(false, false);
                        updateOtaButtonState();
                    });
                    return;
                }
                
                log("发现了 " + services.size() + " 个服务");
                
                // 提取服务UUID列表
                List<String> serviceUUIDs = new ArrayList<>();
                for (BluetoothGattService service : services) {
                    String uuid = service.getUuid().toString().toUpperCase();
                    serviceUUIDs.add(uuid);
                    log("发现服务: " + uuid);
                }
                
                // 检查是否支持OTA（与Flutter端isOtaDevice逻辑保持一致）
                OtaDeviceChecker.OtaDeviceCheckResult result = OtaDeviceChecker.checkOtaDevice(device, serviceUUIDs);
                
                log("OTA服务检查结果: " + result.toString());
                
                runOnUiThread(() -> {
                    if (result.isOtaDevice) {
                        // 设备支持OTA
                        log("✓ 设备支持OTA升级: " + result.message);
                        Toast.makeText(OtaActivity.this, "设备支持OTA升级: " + result.deviceMode.getDescription(), Toast.LENGTH_LONG).show();
                        updateOtaButtonState(); // 启用OTA按钮
                    } else {
                        // 设备不支持OTA，断开连接（与Flutter端保持一致）
                        log("✗ 设备不支持OTA升级: " + result.message);
                        Toast.makeText(OtaActivity.this, "设备不支持OTA升级，已断开连接", Toast.LENGTH_LONG).show();
                        ble.disconnect(device);
                        updateConnectionStatus(false, false);
                        updateOtaButtonState();
                    }
                });
                
            } catch (Exception e) {
                log("服务检查异常: " + e.getMessage());
                runOnUiThread(() -> {
                    Toast.makeText(OtaActivity.this, "服务检查失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                    ble.disconnect(device);
                    updateConnectionStatus(false, false);
                    updateOtaButtonState();
                });
            }
        }, 500); // 延迟500ms确保连接稳定
    }
}
